﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;

namespace GameDriver
{
    /// <summary>
    /// Simple enumeration of DPad directions for use in GamePad input handling.
    /// </summary>
    public enum DPadDirection { Up, Down, Left, Right }

    /// <summary>
    /// A completely static class used to track and retrieve input from a variety of sources.
    /// </summary>
    public static class InputHandler
    {
        #region PRIVATE VARIABLES
        private static KeyboardState KeyboardState = Keyboard.GetState();
        private static KeyboardState OldKeyboardState = Keyboard.GetState();
        private static MouseState MouseState = Mouse.GetState();
        private static MouseState OldMouseState = Mouse.GetState();
        private static Dictionary<PlayerIndex, GamePadState> GamePadState = new Dictionary<PlayerIndex, GamePadState>();
        private static Dictionary<PlayerIndex, GamePadState> OldGamePadState = new Dictionary<PlayerIndex, GamePadState>();
        #endregion
        
        /// <summary>
        /// Used when no player index is supplied to a gamepad input handling method.
        /// </summary>
        public static PlayerIndex CurrentPlayer;

        /// <summary>
        /// Initializes internal variables - should be called once at initialization.
        /// </summary>
        public static void Initialize()
        {
            KeyboardState = Keyboard.GetState();
            OldKeyboardState = Keyboard.GetState();
            MouseState = Mouse.GetState();
            OldMouseState = Mouse.GetState();
            GamePadState = new Dictionary<PlayerIndex,GamePadState>();
            OldGamePadState = new Dictionary<PlayerIndex,GamePadState>();

            GamePadState.Add(PlayerIndex.One, GamePad.GetState(CurrentPlayer));
            GamePadState.Add(PlayerIndex.Two, GamePad.GetState(PlayerIndex.Two));
            GamePadState.Add(PlayerIndex.Three, GamePad.GetState(PlayerIndex.Three));
            GamePadState.Add(PlayerIndex.Four, GamePad.GetState(PlayerIndex.Four));
            
            OldGamePadState.Add(PlayerIndex.One, GamePad.GetState(CurrentPlayer));
            OldGamePadState.Add(PlayerIndex.Two, GamePad.GetState(PlayerIndex.Two));
            OldGamePadState.Add(PlayerIndex.Three, GamePad.GetState(PlayerIndex.Three));
            OldGamePadState.Add(PlayerIndex.Four, GamePad.GetState(PlayerIndex.Four));

            CurrentPlayer = PlayerIndex.One;
        }

        /// <summary>Updates internal variables - should be called exactly once every frame.</summary>
        public static void Update()
        {
            OldKeyboardState = KeyboardState;
            OldMouseState = MouseState;
            OldGamePadState[PlayerIndex.One] = GamePadState[CurrentPlayer];
            OldGamePadState[PlayerIndex.Two] = GamePadState[PlayerIndex.Two];
            OldGamePadState[PlayerIndex.Three] = GamePadState[PlayerIndex.Three];
            OldGamePadState[PlayerIndex.Four] = GamePadState[PlayerIndex.Four];

            KeyboardState = Keyboard.GetState();
            MouseState = Mouse.GetState();
            GamePadState[PlayerIndex.One] = GamePad.GetState(CurrentPlayer);
            GamePadState[PlayerIndex.Two] = GamePad.GetState(PlayerIndex.Two);
            GamePadState[PlayerIndex.Three] = GamePad.GetState(PlayerIndex.Three);
            GamePadState[PlayerIndex.Four] = GamePad.GetState(PlayerIndex.Four);
        }

        #region Public Methods - Keyboard
        /// <summary>
        /// Check if a key is being pressed.
        /// </summary>
        /// <param name="key">The key to check.</param>
        /// <returns>True if the key is being pressed, false if it is up.</returns>
        public static bool IsKeyDown(Keys key)
        {
            return KeyboardState.IsKeyDown(key);
        }
        /// <summary>
        /// Check if a key is not being pressed.
        /// </summary>
        /// <param name="key">The key to check.</param>
        /// <returns>True if the key is up, false if it is being pressed.</returns>
        public static bool IsKeyUp(Keys key)
        {
            return KeyboardState.IsKeyUp(key);
        }
        /// <summary>
        /// Check if a key was pressed between the last two frames.
        /// </summary>
        /// <param name="key">The key to check.</param>
        /// <returns>True if the key is pressed now and was up last frame, false otherwise.</returns>
        public static bool WasKeyPressed(Keys key)
        {
            return KeyboardState.IsKeyDown(key) && OldKeyboardState.IsKeyUp(key);
        }
        /// <summary>
        /// Check if a key was released between the last two frames.
        /// </summary>
        /// <param name="key">The key to check.</param>
        /// <returns>True if the key is up now and was pressed last frame, false otherwise.</returns>
        public static bool WasKeyReleased(Keys key)
        {
            return KeyboardState.IsKeyUp(key) && OldKeyboardState.IsKeyDown(key);
        }
        #endregion

        #region Public Methods - Mouse Position
        /// <summary>
        /// Get the x-coordinate of the mouse on the screen.
        /// </summary>
        /// <returns>An integer representation of the x-coordinate of the mouse.</returns>
        public static int MouseX()
        {
            return MouseState.X;
        }
        /// <summary>
        /// Get the y-coordinate of the mouse on the screen.
        /// </summary>
        /// <returns>An integer representation of the y-coordinate of the mouse.</returns>
        public static int MouseY()
        {
            return MouseState.Y;
        }
        /// <summary>
        /// Get the position of the mouse on the screen.
        /// </summary>
        /// <returns>A vector representaiton of the position of the mouse.</returns>
        public static Vector2 MousePosition()
        {
            return new Vector2(MouseX(), MouseY());
        }
        /// <summary>
        /// Get the change in the scroll wheel value.
        /// </summary>
        /// <returns>An integer representation of scroll delta.</returns>
        public static int GetScrollValue()
        {
            return MouseState.ScrollWheelValue - OldMouseState.ScrollWheelValue;
        }
        #endregion

        #region Public Methods - Primary Mouse Buttons
        /// <summary>
        /// Check if the left mouse button is down.
        /// </summary>
        /// <returns>True if the left mouse button is currently pressed, false if it is up.</returns>
        public static bool IsLeftButtonDown()
        {
            return MouseState.LeftButton == ButtonState.Pressed;
        }
        /// <summary>
        /// Check if the left mouse button is up.
        /// </summary>
        /// <returns>True if the left mouse button is currently up, false if it is pressed.</returns>
        public static bool IsLeftButtonUp()
        {
            return MouseState.LeftButton == ButtonState.Released;
        }
        /// <summary>
        /// Check if the left mouse button was pressed between the last two frames.
        /// </summary>
        /// <returns>True if the left mouse button is pressed now and was up last frame, false otherwise.</returns>
        public static bool WasLeftButtonPressed()
        {
            return MouseState.LeftButton == ButtonState.Pressed && OldMouseState.LeftButton == ButtonState.Released;
        }
        /// <summary>
        /// Check if the left mouse button was released between the last two frames.
        /// </summary>
        /// <returns>True if the left mouse button is up now and was pressed last frame, false otherwise.</returns>
        public static bool WasLeftButtonReleased()
        {
            return MouseState.LeftButton == ButtonState.Released && OldMouseState.LeftButton == ButtonState.Pressed;
        }

        /// <summary>
        /// Check if the right mouse button is down.
        /// </summary>
        /// <returns>True if the right mouse button is currently pressed, false if it is up.</returns>
        public static bool IsRightButtonDown()
        {
            return MouseState.RightButton == ButtonState.Pressed;
        }
        /// <summary>
        /// Check if the right mouse button is up.
        /// </summary>
        /// <returns>True if the right mouse button is currently up, false if it is pressed.</returns>
        public static bool IsRightButtonUp()
        {
            return MouseState.RightButton == ButtonState.Released;
        }
        /// <summary>
        /// Check if the right mouse button was pressed between the last two frames.
        /// </summary>
        /// <returns>True if the right mouse button is pressed now and was up last frame, false otherwise.</returns>
        public static bool WasRightButtonPressed()
        {
            return MouseState.RightButton == ButtonState.Pressed && OldMouseState.RightButton == ButtonState.Released;
        }
        /// <summary>
        /// Check if the right mouse button was released between the last two frames.
        /// </summary>
        /// <returns>True if the right mouse button is up now and was pressed last frame, false otherwise.</returns>
        public static bool WasRightButtonReleased()
        {
            return MouseState.RightButton == ButtonState.Released && OldMouseState.RightButton == ButtonState.Pressed;
        }

        /// <summary>
        /// Check if the middle mouse button is down.
        /// </summary>
        /// <returns>True if the middle mouse button is currently pressed, false if it is up.</returns>
        public static bool IsMiddleButtonDown()
        {
            return MouseState.MiddleButton == ButtonState.Pressed;
        }
        /// <summary>
        /// Check if the middle mouse button is up.
        /// </summary>
        /// <returns>True if the middle mouse button is currently up, false if it is pressed.</returns>
        public static bool IsMiddleButtonUp()
        {
            return MouseState.MiddleButton == ButtonState.Released;
        }
        /// <summary>
        /// Check if the middle mouse button was pressed between the last two frames.
        /// </summary>
        /// <returns>True if the middle mouse button is pressed now and was up last frame, false otherwise.</returns>
        public static bool WasMiddleButtonPressed()
        {
            return MouseState.MiddleButton == ButtonState.Pressed && OldMouseState.MiddleButton == ButtonState.Released;
        }
        /// <summary>
        /// Check if the middle mouse button was released between the last two frames.
        /// </summary>
        /// <returns>True if the middle mouse button is up now and was pressed last frame, false otherwise.</returns>
        public static bool WasMiddleButtonReleased()
        {
            return MouseState.MiddleButton == ButtonState.Released && OldMouseState.MiddleButton == ButtonState.Pressed;
        }
        #endregion

        #region Public Methods - Extra Mouse Buttons
        /// <summary>
        /// Check if the 1st extra mouse button is down.
        /// </summary>
        /// <returns>True if the 1st extra mouse button is currently pressed, false if it is up.</returns>
        public static bool IsXButton1Down()
        {
            return MouseState.XButton1 == ButtonState.Pressed;
        }
        /// <summary>
        /// Check if the 1st extra mouse button is up.
        /// </summary>
        /// <returns>True if the 1st extra mouse button is currently up, false if it is pressed.</returns>
        public static bool IsXButton1Up()
        {
            return MouseState.XButton1 == ButtonState.Released;
        }
        /// <summary>
        /// Check if the 1st extra mouse button was pressed between the last two frames.
        /// </summary>
        /// <returns>True if the 1st extra mouse button is pressed now and was up last frame, false otherwise.</returns>
        public static bool WasXButton1Pressed()
        {
            return MouseState.XButton1 == ButtonState.Pressed && OldMouseState.XButton1 == ButtonState.Released;
        }
        /// <summary>
        /// Check if the 1st extra mouse button was released between the last two frames.
        /// </summary>
        /// <returns>True if the 1st extra mouse button is up now and was pressed last frame, false otherwise.</returns>
        public static bool WasXButton1Released()
        {
            return MouseState.XButton1 == ButtonState.Released && OldMouseState.XButton1 == ButtonState.Pressed;
        }

        /// <summary>
        /// Check if the 2nd extra mouse button is down.
        /// </summary>
        /// <returns>True if the 2nd extra mouse button is currently pressed, false if it is up.</returns>
        public static bool IsXButton2Down()
        {
            return MouseState.XButton2 == ButtonState.Pressed;
        }
        /// <summary>
        /// Check if the 2nd extra mouse button is up.
        /// </summary>
        /// <returns>True if the 2nd extra mouse button is currently up, false if it is pressed.</returns>
        public static bool IsXButton2Up()
        {
            return MouseState.XButton2 == ButtonState.Released;
        }
        /// <summary>
        /// Check if the 2nd extra mouse button was pressed between the last two frames.
        /// </summary>
        /// <returns>True if the 2nd extra mouse button is pressed now and was up last frame, false otherwise.</returns>
        public static bool WasXButton2Pressed()
        {
            return MouseState.XButton2 == ButtonState.Pressed && OldMouseState.XButton2 == ButtonState.Released;
        }
        /// <summary>
        /// Check if the 2nd extra mouse button was released between the last two frames.
        /// </summary>
        /// <returns>True if the 2nd extra mouse button is up now and was pressed last frame, false otherwise.</returns>
        public static bool WasXButton2Released()
        {
            return MouseState.XButton2 == ButtonState.Released && OldMouseState.XButton2 == ButtonState.Pressed;
        }
        #endregion

        #region Public Methods - Game Pad Buttons
        /// <summary>
        /// Check if a button is being pressed by the current player.
        /// </summary>
        /// <param name="button">The button to check.</param>
        /// <returns>True if the button is being pressed, false if it is up.</returns>
        public static bool IsButtonDown(Buttons button)
        {
            return IsButtonDown(CurrentPlayer, button);
        }
        /// <summary>
        /// Check if a button is not being pressed by the current player.
        /// </summary>
        /// <param name="button">The button to check.</param>
        /// <returns>True if the button is up, false if it is being pressed.</returns>
        public static bool IsButtonUp(Buttons button)
        {
            return IsButtonUp(CurrentPlayer, button);
        }
        /// <summary>
        /// Check if a button was pressed between the last two frames by the current player.
        /// </summary>
        /// <param name="button">The button to check.</param>
        /// <returns>True if the button is pressed now and was up last frame, false otherwise.</returns>
        public static bool WasButtonPressed(Buttons button)
        {
            return WasButtonPressed(CurrentPlayer, button);
        }
        /// <summary>
        /// Check if a button was released between the last two frames by the current player.
        /// </summary>
        /// <param name="button">The button to check.</param>
        /// <returns>True if the button is up now and was pressed last frame, false otherwise.</returns>
        public static bool WasButtonReleased(Buttons button)
        {
            return WasButtonReleased(CurrentPlayer, button);
        }

        /// <summary>
        /// Check if a button is being pressed py a specific player.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <param name="button">The button to check.</param>
        /// <returns>True if the button is being pressed, false if it is up.</returns>
        public static bool IsButtonDown(PlayerIndex pi, Buttons button)
        {
            return GamePadState[pi].IsButtonDown(button);
        }
        /// <summary>
        /// Check if a button is not being pressed by a specific player.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <param name="button">The button to check.</param>
        /// <returns>True if the button is up, false if it is being pressed.</returns>
        public static bool IsButtonUp(PlayerIndex pi, Buttons button)
        {
            return GamePadState[pi].IsButtonUp(button);
        }
        /// <summary>
        /// Check if a button was pressed between the last two frames by a specific player.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <param name="button">The button to check.</param>
        /// <returns>True if the button is pressed now and was up last frame, false otherwise.</returns>
        public static bool WasButtonPressed(PlayerIndex pi, Buttons button)
        {
            return GamePadState[pi].IsButtonDown(button) && OldGamePadState[pi].IsButtonUp(button);
        }
        /// <summary>
        /// Check if a button was released between the last two frames by a specific player.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <param name="button">The button to check.</param>
        /// <returns>True if the button is up now and was pressed last frame, false otherwise.</returns>
        public static bool WasButtonReleased(PlayerIndex pi, Buttons button)
        {
            return GamePadState[pi].IsButtonUp(button) && OldGamePadState[pi].IsButtonDown(button);
        }
        #endregion

        #region Public Methods - Game Pad DPad
        /// <summary>
        /// Check if a DPad direction is being pressed by the current player.
        /// </summary>
        /// <param name="direction">The direction to check.</param>
        /// <returns>True if the direction is being pressed, false if it is up.</returns>
        public static bool IsDPadDown(DPadDirection direction)
        {
            return IsDPadDown(CurrentPlayer, direction);
        }
        /// <summary>
        /// Check if a DPad direction is not being pressed by the current player.
        /// </summary>
        /// <param name="direction">The direction to check.</param>
        /// <returns>True if the direction is up, false if it is being pressed.</returns>
        public static bool IsDPadUp(DPadDirection direction)
        {
            return IsDPadUp(CurrentPlayer, direction);
        }
        /// <summary>
        /// Check if a DPad direction was pressed between the last two frames by the current player.
        /// </summary>
        /// <param name="direction">The direction to check.</param>
        /// <returns>True if the direction is pressed now and was up last frame, false otherwise.</returns>
        public static bool WasDPadPressed(DPadDirection direction)
        {
            return WasDPadPressed(CurrentPlayer, direction);
        }
        /// <summary>
        /// Check if a DPad direction was released between the last two frames by the current player.
        /// </summary>
        /// <param name="direction">The direction to check.</param>
        /// <returns>True if the direction is up now and was pressed last frame, false otherwise.</returns>
        public static bool WasDPadReleased(DPadDirection direction)
        {
            return WasDPadReleased(CurrentPlayer, direction);
        }

        /// <summary>
        /// Check if a DPad direction is being pressed py a specific player.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <param name="direction">The direction to check.</param>
        /// <returns>True if the direction is being pressed, false if it is up.</returns>
        public static bool IsDPadDown(PlayerIndex pi, DPadDirection direction)
        {
            switch (direction)
            {
                case DPadDirection.Up:
                    return GamePadState[pi].DPad.Up == ButtonState.Pressed;
                case DPadDirection.Down:
                    return GamePadState[pi].DPad.Down == ButtonState.Pressed;
                case DPadDirection.Left:
                    return GamePadState[pi].DPad.Left == ButtonState.Pressed;
                case DPadDirection.Right:
                    return GamePadState[pi].DPad.Right == ButtonState.Pressed;
            }
            throw new Exception("IsDPadDown() was not passed a valid direction!");
        }
        /// <summary>
        /// Check if a DPad direction is not being pressed by a specific player.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <param name="direction">The direction to check.</param>
        /// <returns>True if the direction is up, false if it is being pressed.</returns>
        public static bool IsDPadUp(PlayerIndex pi, DPadDirection direction)
        {
            switch (direction)
            {
                case DPadDirection.Up:
                    return GamePadState[pi].DPad.Up == ButtonState.Released;
                case DPadDirection.Down:
                    return GamePadState[pi].DPad.Down == ButtonState.Released;
                case DPadDirection.Left:
                    return GamePadState[pi].DPad.Left == ButtonState.Released;
                case DPadDirection.Right:
                    return GamePadState[pi].DPad.Right == ButtonState.Released;
            }
            throw new Exception("IsDPadUp() was not passed a valid direction!");
        }
        /// <summary>
        /// Check if a DPad direction was pressed between the last two frames by a specific player.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <param name="direction">The direction to check.</param>
        /// <returns>True if the direction is pressed now and was up last frame, false otherwise.</returns>
        public static bool WasDPadPressed(PlayerIndex pi, DPadDirection direction)
        {
            switch (direction)
            {
                case DPadDirection.Up:
                    return GamePadState[pi].DPad.Up == ButtonState.Pressed && OldGamePadState[pi].DPad.Up == ButtonState.Released;
                case DPadDirection.Down:
                    return GamePadState[pi].DPad.Down == ButtonState.Pressed && OldGamePadState[pi].DPad.Down == ButtonState.Released;
                case DPadDirection.Left:
                    return GamePadState[pi].DPad.Left == ButtonState.Pressed && OldGamePadState[pi].DPad.Left == ButtonState.Released;
                case DPadDirection.Right:
                    return GamePadState[pi].DPad.Right == ButtonState.Pressed && OldGamePadState[pi].DPad.Right == ButtonState.Released;
            }
            throw new Exception("WasDPadPressed() was not passed a valid direction!");
        }
        /// <summary>
        /// Check if a DPad direction was released between the last two frames by a specific player.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <param name="direction">The direction to check.</param>
        /// <returns>True if the direction is up now and was pressed last frame, false otherwise.</returns>
        public static bool WasDPadReleased(PlayerIndex pi, DPadDirection direction)
        {
            switch (direction)
            {
                case DPadDirection.Up:
                    return GamePadState[pi].DPad.Up == ButtonState.Released && OldGamePadState[pi].DPad.Up == ButtonState.Pressed;
                case DPadDirection.Down:
                    return GamePadState[pi].DPad.Down == ButtonState.Released && OldGamePadState[pi].DPad.Down == ButtonState.Pressed;
                case DPadDirection.Left:
                    return GamePadState[pi].DPad.Left == ButtonState.Released && OldGamePadState[pi].DPad.Left == ButtonState.Pressed;
                case DPadDirection.Right:
                    return GamePadState[pi].DPad.Right == ButtonState.Released && OldGamePadState[pi].DPad.Right == ButtonState.Pressed;
            }
            throw new Exception("WasDPadReleased() was not passed a valid direction!");
        }
        #endregion

        #region Public Methods - Game Pad Triggers and Sticks
        /// <summary>
        /// Check the current position of the left trigger on the current player's gamepad.
        /// </summary>
        /// <returns>The position of the trigger from 0.0f (untouched) to 1.0f (pulled completely).</returns>
        public static float LeftTrigger()
        {
            return LeftTrigger(CurrentPlayer);
        }
        /// <summary>
        /// Check the change in position of the left trigger on the current player's gamepad.
        /// </summary>
        /// <returns>The change in the position of the trigger as a float.</returns>
        public static float LeftTriggerDelta()
        {
            return LeftTriggerDelta(CurrentPlayer);
        }
        /// <summary>
        /// Check the current position of the right trigger on the current player's gamepad.
        /// </summary>
        /// <returns>The position of the trigger from 0.0f (untouched) to 1.0f (pulled completely).</returns>
        public static float RightTrigger()
        {
            return RightTrigger(CurrentPlayer);
        }
        /// <summary>
        /// Check the change in position of the right trigger on the current player's gamepad.
        /// </summary>
        /// <returns>The change in the position of the trigger as a float.</returns>
        public static float RightTriggerDelta()
        {
            return RightTriggerDelta(CurrentPlayer);
        }

        /// <summary>
        /// Check the current position of the left trigger on the given player's gamepad.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <returns>The position of the trigger from 0.0f (untouched) to 1.0f (pulled completely).</returns>
        public static float LeftTrigger(PlayerIndex pi)
        {
            return GamePadState[pi].Triggers.Left;
        }
        /// <summary>
        /// Check change in the current position of the left trigger on the given player's gamepad.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <returns>The change in the position of the trigger as a float.</returns>
        public static float LeftTriggerDelta(PlayerIndex pi)
        {
            return GamePadState[pi].Triggers.Left - OldGamePadState[pi].Triggers.Left;
        }
        /// <summary>
        /// Check the current position of the right trigger on the given player's gamepad.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <returns>The position of the trigger from 0.0f (untouched) to 1.0f (pulled completely).</returns>
        public static float RightTrigger(PlayerIndex pi)
        {
            return GamePadState[pi].Triggers.Right;
        }
        /// <summary>
        /// Check change in the current position of the right trigger on the given player's gamepad.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <returns>The change in the position of the trigger as a float.</returns>
        public static float RightTriggerDelta(PlayerIndex pi)
        {
            return GamePadState[pi].Triggers.Right - OldGamePadState[pi].Triggers.Right;
        }


        /// <summary>
        /// Check the current position of the left stick on the current player's gamepad.
        /// </summary>
        /// <returns>The position of the stick as a vector with -1<x<1 and -1<y<1.</returns>
        public static Vector2 LeftStick()
        {
            return LeftStick(CurrentPlayer);
        }
        /// <summary>
        /// Check the change in the position of the left stick on the current player's gamepad.
        /// </summary>
        /// <returns>The change in the position of the stick as a vector.</returns>
        public static Vector2 LeftStickDelta()
        {
            return LeftStickDelta(CurrentPlayer);
        }
        /// <summary>
        /// Check the current position of the right stick on the current player's gamepad.
        /// </summary>
        /// <returns>The position of the stick as a vector with -1<x<1 and -1<y<1.</returns>
        public static Vector2 RightStick()
        {
            return RightStick(CurrentPlayer);
        }
        /// <summary>
        /// Check the change in the position of the right stick on the current player's gamepad.
        /// </summary>
        /// <returns>The change in the position of the stick as a vector.</returns>
        public static Vector2 RightStickDelta()
        {
            return RightStickDelta(CurrentPlayer);
        }

        /// <summary>
        /// Check the current position of the left stick on the given player's gamepad.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <returns>The position of the stick as a vector with -1<x<1 and -1<y<1.</returns>
        public static Vector2 LeftStick(PlayerIndex pi)
        {
            return GamePadState[pi].ThumbSticks.Left;
        }
        /// <summary>
        /// Check the change in the position of the left stick on the given player's gamepad.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <returns>The change in the position of the stick as a vector.</returns>
        public static Vector2 LeftStickDelta(PlayerIndex pi)
        {
            return GamePadState[pi].ThumbSticks.Left - OldGamePadState[pi].ThumbSticks.Left;
        }
        /// <summary>
        /// Check the current position of the right stick on the give player's gamepad.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <returns>The position of the stick as a vector with -1<x<1 and -1<y<1.</returns>
        public static Vector2 RightStick(PlayerIndex pi)
        {
            return GamePadState[pi].ThumbSticks.Right;
        }
        /// <summary>
        /// Check the change in the position of the right stick on the give player's gamepad.
        /// </summary>
        /// <param name="pi">The player index to query.</param>
        /// <returns>The change in the position of the stick as a vector.</returns>
        public static Vector2 RightStickDelta(PlayerIndex pi)
        {
            return GamePadState[pi].ThumbSticks.Right - OldGamePadState[pi].ThumbSticks.Right;
        }
        #endregion
    }
}
